Interact properly with shells lacking job control (sh, rc, es...)
authorJim Blandy <jimb@redhat.com>
Fri, 11 Jun 1993 16:22:03 +0000 (16:22 +0000)
committerJim Blandy <jimb@redhat.com>
Fri, 11 Jun 1993 16:22:03 +0000 (16:22 +0000)
* sysdep.c [BSD] (inherited_pgroup): New variable.
(narrow_foreground_group, widen_foreground_group): New functions.
(init_sys_modes): Call narrow_foreground_group.
(reset_sys_modes): Call widen_foreground_group.
* emacs.c [BSD] (inherited_pgroup): Add extern declaration.
[BSD] (main): Set inherited_pgroup, and put ourselves in our own
pgroup.

src/emacs.c
src/sysdep.c

index 3f9420f2d0add61e0abfacbea9d58dacddd59b4c..026d669cf0dc5794809d83b544674fe8f0088b94 100644 (file)
@@ -81,6 +81,11 @@ int inhibit_window_system;
    priority; Those functions have their own extern declaration.  */
 int emacs_priority;
 
+#ifdef BSD
+/* See sysdep.c.  */
+extern int inherited_pgroup;
+#endif
+
 #ifdef HAVE_X_WINDOWS
 /* If non-zero, -d was specified, meaning we're using some window system. */
 int display_arg;
@@ -292,18 +297,19 @@ main (argc, argv, envp)
 #endif
 
   clearerr (stdin);
-#if 0 /* Without EMACS_SET_TTY_PGRP, this causes Emacs to hang
-        when run under a non-job-control shell.
-        EMACS_SET_TTY_PGRP seems correct, but breaks even more.  */
+
 #ifdef BSD
   {
-    int pid = getpid ();
-    setpgrp (0, pid);
-    EMACS_SET_TTY_PGRP (0, &pid);
-  }
+#ifdef GETPGRP_NO_ARG
+    inherited_pgroup = getpgrp (0);
+#else /* THISSENTENCE_NO_VERB */
+    inherited_pgroup = getpgrp (0);
 #endif
+    setpgrp (0, getpid ());
+  }
 #endif
 
+
 #ifdef APOLLO
 #ifndef APOLLO_SR10
   /* If USE_DOMAIN_ACLS environment variable exists,
index 49744430560b90dd53fa93e05e5f786b4919088c..247b9b2314fa5b607c106813257f5d75a327998b 100644 (file)
@@ -756,6 +756,54 @@ unrequest_sigio ()
 #endif /* FASYNC */
 #endif /* F_SETFL */
 \f
+/* Saving and restoring the process group of Emacs's terminal.  */
+
+#ifdef BSD
+
+/* The process group of which Emacs was a member when it initially
+   started.
+
+   If Emacs was in its own process group (i.e. inherited_pgroup ==
+   getpid ()), then we know we're running under a shell with job
+   control (Emacs would never be run as part of a pipeline).
+   Everything is fine.
+
+   If Emacs was not in its own process group, then we know we're
+   running under a shell (or a caller) that doesn't know how to
+   separate itself from Emacs (like sh).  Emacs must be in its own
+   process group in order to receive SIGIO correctly.  In this
+   situation, we put ourselves in our own pgroup, forcibly set the
+   tty's pgroup to our pgroup, and make sure to restore and reinstate
+   the tty's pgroup just like any other terminal setting.  If
+   inherited_group was not the tty's pgroup, then we'll get a
+   SIGTTmumble when we try to change the tty's pgroup, and a CONT if
+   it goes foreground in the future, which is what should happen.  */
+int inherited_pgroup;
+
+/* Split off the foreground process group to Emacs alone.
+   When we are in the foreground, but not started in our own process
+   group, redirect the TTY to point to our own process group.  We need
+   to be in our own process group to receive SIGIO properly.  */
+narrow_foreground_group ()
+{
+  int me = getpid ();
+
+  setpgrp (0, inherited_pgroup);
+  if (inherited_pgroup != me)
+    EMACS_SET_TTY_PGRP (0, &me);
+  setpgrp (0, me);
+}
+
+/* Set the tty to our original foreground group.  */
+widen_foreground_group ()
+{
+  if (inherited_pgroup != getpid ())
+    EMACS_SET_TTY_PGRP (0, &inherited_pgroup);
+  setpgrp (0, inherited_pgroup);
+}
+
+#endif
+\f
 /* Getting and setting emacs_tty structures.  */
 
 /* Set *TC to the parameters associated with the terminal FD.
@@ -982,6 +1030,11 @@ init_sys_modes ()
 #endif
 #endif /* not VMS */
 
+#ifdef BSD
+  if (! read_socket_hook && EQ (Vwindow_system, Qnil))
+    narrow_foreground_group ();
+#endif
+
   EMACS_GET_TTY (input_fd, &old_tty);
 
   if (!read_socket_hook && EQ (Vwindow_system, Qnil))
@@ -1334,6 +1387,10 @@ reset_sys_modes ()
 #ifdef AIX
   hft_reset ();
 #endif
+
+#ifdef BSD
+  widen_foreground_group ();
+#endif
 }
 \f
 #ifdef HAVE_PTYS